<template>
  <a-result v-if="!auth && noMatch" :staus="403" title="403" sub-title="无权限" />
  <slot v-else-if="auth" />
</template>

<script lang="ts">
import { Action, Role } from '@/api/system/core/typing';
import { isArray } from 'lodash-es';
import { computed, ref, defineComponent, PropType, VNodeChild } from 'vue';
import { useStore } from 'vuex';

export type AuthorityType = string | string[] | ((authority: Action[]) => boolean);

export default defineComponent({
  name: 'Authority',
  props: {
    authority: {
      type: [String, Array, Function] as PropType<AuthorityType>,
      default: () => true,
    },
    noMatch: {
      type: [String, Boolean, Object] as PropType<string | boolean | VNodeChild>,
      default: () => undefined,
    },
  },
  setup(props) {
    const store = useStore();
    const roles = computed<Role[]>(() => store.getters['user/roles']);
    const auth = ref(false);

    if (roles.value && roles.value.length > 0) {
      const actions = roles.value.map(role => role.actions).flat();
      const isArr = isArray(props.authority);

      if (typeof props.authority === 'string' || isArr) {
        auth.value = actions.some(value => {
          return isArr
            ? (props.authority as string[]).includes((value?.name) ? value.name : '')
            : props.authority === value?.name;
        });
      } else if (typeof props.authority === 'function') {
        auth.value = props.authority((actions as Action[]));
      }
    }

    return {
      auth,
    };
  },
});
</script>
